using System.ComponentModel;
using GeneticAlgorithms.Genomes;
using GeneticAlgorithms.Populations;

namespace GeneticAlgorithms
{
    /// <summary>
    /// Base interface for Genetic Algorithm
    /// implementations.
    /// </summary>
    public interface IGeneticAlgorithm
    {
        /// <summary>
        /// Gets or sets the GA configuration.
        /// </summary>
        /// <value>The configuration that dictates the GA behavior.</value>
        IGAConfiguration Configuration { get; set; }

        /// <summary>
        /// Gets the GA status.
        /// </summary>
        /// <value>The GA status.</value>
        IGAStatus Status { get; }

        /// <summary>
        /// Initializes the Genetic Algorithm.
        /// </summary>
        void Initialize();

        /// <summary>
        /// Performs a single evolutionary step.
        /// </summary>
        void DoStep();

        /// <summary>
        /// Starts evolution. Causes the genomes to evolve
        /// until one of the stop conditions has been met.
        /// </summary>
        void Evolve();

        /// <summary>
        /// Occurs after each evolutionary step.
        /// </summary>
        event CancelEventHandler Stepped;

        /// <summary>
        /// Gets the best genome in the population.
        /// </summary>
        /// <returns>
        /// The fittest genome in the population.
        /// </returns>
        IGenomeBase GetBest();
    }

    /// <summary>
    /// Base generic interface for genetic algorithms.
    /// </summary>
    /// <typeparam name="TGenome">The type of the genome.</typeparam>
    /// <typeparam name="TGene">The type of the gene.</typeparam>
    public interface IGeneticAlgorithm<TGenome, TGene> : IGeneticAlgorithm
        where TGenome : IGenome<TGene>
    {
        /// <summary>
        /// Gets the GA population.
        /// </summary>
        /// <value>The GA population.</value>
        IPopulation<TGenome, TGene> Population { get; }
    }
}
